﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Week1.world.behavior
{
    abstract public class ABehavior
    {
        public enum BehaviorID : int { grid, move, revolve, path, shoot, shotat };

        /// <summary>
        /// Called from loadcontent or initialize to load the default values. 
        /// This method can change oVars based on behavior
        /// </summary>
        /// <param name="handlerid"></param>
        /// <param name="oVars"></param>
        abstract public void initialize(int handlerid, DrawableGlobalVar oVars);

        /// <summary>
        /// Executes a behavior
        /// </summary>
        /// <param name="handlerid">hendlerid</param>
        /// <param name="oVars"></param>
        abstract public void execute(int handlerid, DrawableGlobalVar oVars, GameTime gameTime);

        /// <summary>
        /// Create a space in behavior memory and returns a handler id.
        /// </summary>
        /// <param name="oVars"></param>
        /// <returns>handlerid. use it with consective calls</returns>
        abstract public int getBehaviorHandlerID(DrawableGlobalVar oVars);
        
        /// <summary>
        /// set by drawabe objects and used by behavior. 
        /// Set it to null if drawable is dead and need to be unload from memory. 
        /// call this from content unload of drawable to free the memory.
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="trigger"></param>
        abstract public void setTrigger(int handler, TriggerKey trigger);

        /// <summary>
        /// Behavior property such as target location etc. Each behavior has its own property. 
        /// Method is expensive and should be called rarely.
        /// </summary>
        /// <param name="handlerID">handler id of the behavior</param>
        /// <param name="instanceIndex">instance index of model for which the property is assigned. This parameter is ignored for now</param>
        /// <param name="name">name of the property</param>
        /// <param name="oVal">value of the property</param>
        abstract public void setBehaviorProperty(int handlerID, int instanceIndex, string name, int value);
        abstract public void setBehaviorProperty(int handler, int instanceIndex, string name, float value);
        abstract public void setBehaviorProperty(int handler, int instanceIndex, string name, long[] value);
        abstract public void setBehaviorProperty(int handler, int instanceIndex, string name, string value);
        abstract public void setBehaviorProperty(int handler, int instanceIndex, string name, ref Vector3 value);
        abstract public void setBehaviorProperty(int handler, int instanceIndex, string name, Vector3[] value);
        abstract public void setBehaviorProperty(int handler, int instanceIndex, string name, DrawableGlobalVar value);
        abstract public void setBehaviorProperty(int handler, int instanceIndex, string name, Vector2[] value);
    }

}